iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
Kubernetes

當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 系列 第 10

認識 Horizontal Pod Autoscaling(HPA)

  • 分享至 

  • xImage
  •  

本次目標

  1. 了解 HPA
  2. HPA 應用模擬

預設上,需要裝 Metrics-server 來進行 CPU/Memory 監控。

$ helm --kubeconfig ~/.kube/infrlab upgrade --install metrics-server --version 3.12.1 metrics-server/metrics-server --create-namespace -n monitor

在 K3d 環境中會自動安裝。

HPA 是什麼

HPA(HorizontalPodAutoscaler)用於自動更新負載資源,會針對 DeploymentStatefulSet 等資源。目的是自動縮長工作負載以滿足需求。對於 DaemonSet 資源是無法使用 HPA。

HPA 是屬於水平擴展,與 VPA 垂直擴展不同。VPA 是針對於記憶體或 CPU 並對當前運行的 Pod 進行擴展。

資源決定了 HPA 控制器的行為,會定期調整其目標(Deployment)的所需規模,以符合觀察到的指標,例如:平均 CPU 使用率、平均記憶體使用率或任何其他指定的自訂指標。同時 HPA 添加了縮放速率配置參數,以控制縮放速率。

HPA 是一個迴圈實現,由 kube-controller-manager--horizontal-pod-autoscaler-sync-period 參數設定,預設 15s。

每段時間內,控制管理器(control management) 會依據 HPA 定義中指定的指標獲取資源使用率。控制管理器找 scaleTargetRef 定義的資源目標,並關聯其 Pod,並從 Metric API 針對每個 Pod 的資源指標或自訂指標取得指標 API。

HPA 定義

定義好的 HorizontalPodAutoscaler 資源如下:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  annotations:
    app.quarkus.io/quarkus-version: 3.9.4
    app.quarkus.io/commit-id: 260a13c09b391a4a1edb357fb2d305523cfbf9d5
    app.quarkus.io/vcs-uri: https://github.com/CCH0124/O11y-with-quarkus.git
    app.quarkus.io/build-timestamp: 2024-04-27 - 10:36:18 +0000
  labels:
    app.kubernetes.io/name: quarkus-hpa
    app.kubernetes.io/version: 1.0.0-SNAPSHOT
    app.kubernetes.io/managed-by: quarkus
  name: quarkus-hpa
  namespace: itachi
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: quarkus-hpa
  minReplicas: 1
  maxReplicas: 25
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 200
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
      - type: Percent
        value: 40
        periodSeconds: 60    
  1. 使用 HorizontalPodAutoscaler 資源
  2. 透過 scaleTargetRef 綁定某資源,下面為 Deployment
  3. 定義最小和最大的數量(minReplicas/maxReplicas)
  4. HorizontalPodAutoscaler.spec.metrics 欄位是用於觸發副本數量的規範,而副本數透過將目標值(HorizontalPodAutoscaler.spec.metrics.type.resource.target)與當前值之間的比率乘以當前 Pod 數量來計算,官方的演算定義如下
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

HorizontalPodAutoscaler.spec.metrics.type 能夠定義不同的指標類型像是 ContainerResourceExternalObjectPodsResource,來滿足不同需求可能是流量等。如果沒有設置,則預設指標將設定為 80% 的平均 CPU 使用率。本文章實驗範例是使用 Resource

  1. Resource 指標是指 Kubernetes Pod 的 CPU 和記憶體使用率與 Pod 規範的限制和請求中提供的值相比。Kubernetes 透過 Metric Server 獲取這些指標。在將這些值與目標值進行比較之前,會先將這些值平均。也就是說,如果應用程式正在運行三個副本,則將計算利用率值的平均值,並將其與部署規範中定義的 CPU 和記憶體請求進行比較。

HorizontalPodAutoscaler.spec.metrics.resource (ResourceMetricSource) 是指 Kubernetes 已知的資源指標像是請求和限制中指定的資源指標,並描述當前擴縮目標(HorizontalPodAutoscaler.spec.metrics.type.resource.target) 例如 CPU 或記憶體然後針對每個 Pod。

ResourceMetricSource 指示如何根據請求和限制中指定的 Kubernetes 已知資源指標進行擴縮容,同時描述目前擴展目標中每個 Pod 的 CPU/Memory。在與目標值比較之前,這些指標值將會被平均。

縮放行為

在實驗所提供的 HPA 範例檔案,有定義了 behavior 字段。其讓縮放行為可被調整或用來穩定縮放過程。這將單一擴展行為策略或多個擴展行為策略附加到 HPA,並且會自動選擇導致給定實例的最大更改量的策略。

...
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 200
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
      - type: Percent
        value: 10
        periodSeconds: 60

periodSeconds 以上面範例來看,表示 HPA 每 60 秒會計算一次期望副本(desiredReplicas)數。

略過 stabilizationWindowSeconds 配置,上述的範例提供兩個策略。如果有 100 個副本正在運行,HPA 將查看兩個可用的策略。第一個策略是自動縮放在 60 秒內一次刪除 2 個 Pod;第二個策略是自動縮放器在 60 秒內刪除目前副本數量的 $10%$。而第二個策略影響最大,因為它將在前 60 秒的移動窗口刪除 10 個 Pod。因此剩下 $100-10$ 個 Pod。在接下來的 60 秒移動窗口中,將從剩餘 90 個 Pod 中刪除 $900.1 = 9$ 個 Pod,剩下 81 個 Pod。接著 60 秒移動窗口,$81 - ceil(810.1) = 72$。當副本達到 20 個時,第一個策略將接管,因為第二個策略的影響會比 2 個 Pod 的影響要小。因此,從 20 個 Pod 開始,自動縮放器將在每次迭代中不斷刪除 2 個 Pod。對於 Policy 是指當下可以最多縮容或擴展 Pod 數量,並非是要設定的值。

stabilizationWindowSeconds 用於透過觀察指定時間段的歷史資料來限制縮放決策。這有助於防止 HPA 在短時間內做出多個縮減決策,從而導致副本數反覆上下波動。假設指標顯示目標應該縮小時,演算法會查看先前計算的所需狀態,並使用指定間隔中的最高值。在演示範例中,將考慮過去 200 秒的所有所需狀態。這近似於滾動最大值,並避免縮放演算法頻繁刪除 Pod,只是為了稍後觸發重新建立等效的 Pod。以上面的範例,表示 HPA 在決定縮減 Pod 數量之前,會考慮過去 200 秒内計算出的最高期望副本數。

stabilizationWindowSeconds 為 0,則表示不應延遲,應立即改變副本的數量。

在縮容時,應該在最後一個 stableWindowSeconds 期間選擇最安全且最大的期望副本數量;在擴容時,應該在最後一個 stableWindowSeconds 期間選擇最安全且最小的期望副本數量。這可以參考原始碼

根據上述的範例,兩者如何協同工作防止 Pod 數量抖動?

  1. 透過 periodSeconds,來根據當前資源計算出期望值
  2. 在決定實際縮減 Pod 數量之前,HPA 會回顧過去 stabilizationWindowSeconds (範例中為 200 秒) 內計算出的所有期望副本數,並選擇其中最高的那個值作為縮減依據

另一方面 behavior 配置目標縮放行為,分別為 scaleUpscaleDown 欄位。如果未設置,則使用預設的 HPAScalingRules 進行縮放。預設行為如下配置

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selectPolicy: Max

對於 scaleDown,穩定視窗(stabilizationWindowSeconds) 為 300 秒或 --horizontal-pod-autoscaler-downscale-stabilization 標誌的值。scaleDown 的策略只有一個,該策略允許刪除 $100%$ 目前正在運行的副本,這表示著可以縮小到允許的最小副本。對於 scaleUp 來說,沒有穩定視窗,值為 0。當指標顯示目標應該擴大時,目標會立即擴大。scaleUp 有 2 個策略,分別是每 15 秒增加 4 個 Pod100% 擴大目前正在運行的副本,直到 HPA 達到穩定狀態。

selectPolicy 字段則是選擇策略中影響最大或最小數量 Pod 的策略。其也可以是 disable。如果未設置,則使用預設值 Max

使用場景

  1. 快速擴張回應高流量的請求
behavior:
  scaleUp:
    policies:
    - type: Percent
      value: 200
      periodSeconds: 30

200,表示以 2 被方式增長。如果應用程式以 1 個 Pod 啟動,它透過以下數量 Pod 進行擴展,並快速擴展至符合當下場景的數量

1 -> 3 -> 9 -> 27
  1. 逐漸縮小規模且快速擴張
    當不想冒險快速縮小規模。下面配置是擴張行為很快;而縮小目標每 10 分鐘只會減少 1 個 Pod。
behavior:
  scaleUp:
    policies:
    - type: Percent
      value: 200
      periodSeconds: 60
  scaleDown:
    policies:
    - type: Pods
      value: 1
      periodSeconds: 600
  1. 擴大規模,但不縮小規模
behavior:
  scaleDown:
    selectPolicy: Disabled
  1. 穩定縮小規模
behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Pods
      value: 5
      periodSeconds: 60
  • 收集 300 秒數據,決定是否要進行縮容
  • 選擇最大的一個
  • 每分鐘縮小不超過 5 個 Pod

假設當前副本為 10 且 HPA 控制器每分鐘循環一次:

  1. 前 4 分鐘,演算法除了收集副本數據之外什麼都不做。假設有以下建議數據 [10, 9, 8, 9]
  2. 第 5 分鐘,再增加一項建議數據 [10, 9, 8, 9, 8]。當中最大的值是 10。因此它不會改變副本的數量。
  3. 第 6 分鐘,再增加一個建議 [9, 8, 9, 8, 7] 並刪除第一個推薦數據以保持相同視窗數量的推薦數據。此演算法選擇最大值 9 並將副本數量變更從 10 變成 9

下個章節會實際使用 Quarkus 服務進行演示。


上一篇
Quarkus 最後一哩路,把它走完吧!
下一篇
當 Quarkus 遇到 HPA
系列文
當 Quarkus 想要騎乘駱駝並用8腳章魚掌控舵手 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言